home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GDEVADMP.C < prev    next >
C/C++ Source or Header  |  1993-05-19  |  7KB  |  196 lines

  1. /* Copyright (C) 1989-1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* This is a bare bones driver I developed for my apple Dot Matrix Printer.
  20.  * This code originally was from the epson driver, but I removed a lot
  21.  * of stuff that was not needed.
  22.  *
  23.  * The Dot Matrix Printer was a predecessor to the apple Imagewriter.  Its
  24.  * main difference being that it was parallel.
  25.  *
  26.  * This code should work fine on Imagewriters, as they have a superset
  27.  * of commands compared to the DMP printer.
  28.  *
  29.  * This driver does not produce the smalles output files possible.  To
  30.  * do that, it should look through the output strings and find repeat
  31.  * occurances of characters, and use the escape sequence that allows
  32.  * printing repeat sequences.  However, as I see it, this the limiting
  33.  * factor in printing is not transmission speed to the printer itself,
  34.  * but rather, how fast the print head can move.  This is assuming the
  35.  * printer is set up with a reasonable speed (9600 bps)
  36.  *
  37.  * WHAT THE CODE DOES AND DOES NOT DO:
  38.  *
  39.  * To print out images, it sets the printer for unidirection printing
  40.  * and 15 cpi (120 dpi). IT sets line feed to 1/9 of an inch (72 dpi).
  41.  * When finished, it sets things back to bidirection print, 1/8" line
  42.  * feeds, and 12 cpi.  There does not appear to be a way to reset
  43.  * things to initial values.
  44.  *
  45.  * This code does not set for 8 bit characters (which is required). It
  46.  * also assumes that carriage return/newline is needed, and not just
  47.  * carriage return.  These are all switch settings on the DMP, and
  48.  * I have configured them for 8 bit data and cr only.
  49.  *
  50.  * You can search for the strings Init and Reset to find the strings
  51.  * that set up the printer and clear things when finished, and change
  52.  * them to meet your needs.
  53.  *
  54.  * Also, you need to make sure that the printer daemon (assuming unix)
  55.  * doesn't change the data as it is being printed.  I have set my
  56.  * printcap file (sunos 4.1.1) with the string:
  57.  * ms=pass8,-opost
  58.  * and it works fine.
  59.  *
  60.  * Feel free to improve this code if you want.  However, please make
  61.  * sure that the old DMP will still be supported by any changes.  This
  62.  * may mean making an imagewriter device, and just copying this file
  63.  * to something like gdevimage.c.
  64.  *
  65.  * The limiting factor of the DMP is the vertical resolution.  However, I
  66.  * see no way to do anything about this.  Horizontal resolution could
  67.  * be increased by using 17 cpi (136 dpi).  I believe the Imagewriter
  68.  * supports 24 cpi (192 dpi).  However, the higher dpi, the slower
  69.  * the printing.
  70.  *
  71.  * Dot Matrix Code by Mark Wedel (master@cats.ucsc.edu)
  72.  */
  73.  
  74.  
  75. #include "gdevprn.h"
  76.  
  77. #ifndef X_DPI
  78. #  define X_DPI 120
  79. #endif
  80.  
  81. #ifndef Y_DPI
  82. #  define Y_DPI 72
  83. #endif
  84.  
  85. /* The device descriptors */
  86. private dev_proc_print_page(dmp_print_page);
  87.  
  88. /* Standard DMP device */
  89. gx_device_printer gs_dmp_device =
  90.   prn_device(prn_std_procs, "dmp",
  91.     85,                /* width_10ths, 8.5" */
  92.     110,                /* height_10ths, 11" */
  93.     X_DPI, Y_DPI,
  94.     0, 0, 0.5, 0,        /* margins */
  95.     1, dmp_print_page);
  96.  
  97.  
  98. /* ------ Internal routines ------ */
  99.  
  100.  
  101. /* Send the page to the printer. */
  102. private int
  103. dmp_print_page(gx_device_printer *pdev, FILE *prn_stream)
  104. {    
  105.  
  106.     int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
  107.     /* Note that in_size is a multiple of 8. */
  108.     int in_size = line_size * 8;
  109.     byte *buf1 = (byte *)gs_malloc(in_size, 1, "eps_print_page(buf1)");
  110.     byte *buf2 = (byte *)gs_malloc(in_size, 1, "eps_print_page(buf2)");
  111.     byte *in = buf1;
  112.     byte *out = buf2;
  113.     int lnum = 0;
  114.  
  115.     /* Check allocations */
  116.     if ( buf1 == 0 || buf2 == 0 )
  117.     {    if ( buf1 ) 
  118.           gs_free((char *)buf1, in_size, 1, "eps_print_page(buf1)");
  119.         if ( buf2 ) 
  120.           gs_free((char *)buf2, in_size, 1, "eps_print_page(buf2)");
  121.         return_error(gs_error_VMerror);
  122.     }
  123.  
  124.     /* Initialize the printer and reset the margins. */
  125.     fwrite("\r\n\033>\033q\033T16", 1, 10, prn_stream);
  126.  
  127.     /* Print lines of graphics */
  128.     while ( lnum < pdev->height )
  129.     {    
  130.         byte *inp;
  131.         byte *in_end;
  132.         byte *out_end;
  133.         int lcnt;
  134.         register byte *out_blk;
  135.  
  136. /* The apple DMP printer seems to be odd in that the bit order on
  137.  * each line is reverse what might be expected.  Meaning, an
  138.  * underscore would be done as a series of 0x80, while on overscore
  139.  * would be done as a series of 0x01.  So we get each
  140.  * scan line in reverse order.
  141.  */
  142.  
  143.         for (lcnt=0; lcnt<8; lcnt++) {
  144.             if ((lnum+lcnt)>pdev->height) 
  145.                 memset(in+lcnt*line_size, 0, line_size);
  146.             else
  147.                 gdev_prn_copy_scan_lines(pdev, lnum+lcnt,
  148.                     in + line_size*(7 - lcnt), line_size);
  149.         }
  150.  
  151.         out_end = out;
  152.         inp = in;
  153.         in_end = inp + line_size;
  154.     
  155.                    for ( ; inp < in_end; inp++, out_end += 8 )
  156.                        { 
  157.                         gdev_prn_transpose_8x8(inp, 
  158.                                line_size, out_end, 1);
  159.                 }
  160.             /* Remove trailing 0s. */
  161.              while ( out_end > out && out_end[-1] == 0 )
  162.                 {
  163.                        out_end--;
  164.             }
  165.         for (out_blk = out; out_blk< out_end; ) {
  166.             /* skip leading 0s */
  167.             if (*out_blk) break;
  168.             out_blk ++;
  169.         }
  170.         /* write out however many blank's as we got nulls.
  171.          * In fact, because of the overhead, this is only really
  172.          * efficient if you have 8 or more leading 0's.
  173.          */
  174.         if ((out_blk!=out) && ((out_blk-out)>7))
  175.             fprintf(prn_stream,"\033V%04d%c", (int) (out_blk-out), 0);
  176.         else
  177.             out_blk=out;
  178.  
  179.         if ((int)(out_end-out_blk)) {
  180.             fprintf(prn_stream,"\033G%04d",(int)(out_end - out_blk));
  181.             fwrite(out_blk, 1, (int)(out_end-out_blk), prn_stream);
  182.         }
  183.         fprintf(prn_stream,"\r\n");
  184.     
  185.         lnum += 8 ;
  186.     }
  187.  
  188.     /* Formfeed and Reset printer */
  189.     fputs("\f\033<\033B\033E", prn_stream);
  190.     fflush(prn_stream);
  191.  
  192.     gs_free((char *)buf2, in_size, 1, "eps_print_page(buf2)");
  193.     gs_free((char *)buf1, in_size, 1, "eps_print_page(buf1)");
  194.     return 0;
  195. }
  196.